www.gusucode.com > VC++ 酒店管理系统-源码程序 > VC++ 酒店管理系统-源码程序/code/hotel2003/CoolTipCtrl.cpp

    //Download by http://www.NewXing.com
/*########################################################################
	Filename: 	cooltipctrl.cpp
	----------------------------------------------------
	Remarks:	...
	----------------------------------------------------
	Author:		成真
	Email:		anyou@sina.com
				anyou@msn.com
	Created:	23/3/2003 19:20
  ########################################################################*/

#include "stdafx.h"
#include "CoolTipCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


#define TIMER_DELAY  1
#define TIMER_FADE   2
#define TIMER_PTTEST 3

/*########################################################################
						-------------------------
							    Construction
						-------------------------
  ########################################################################*/
CCoolTipCtrl::CCoolTipCtrl()
{
	m_nSize		 = CSize(10, 10);
	m_nFade		 = 0;
	m_nDelayTime = 10;
	m_rcRect	 = CRect(0, 0, 8888, 6666);
	m_crBk		 = RGB(250, 255, 225);
	m_crText	 = RGB(0, 0, 0);
	m_crTitle	 = RGB(0, 0, 0);
	m_hIcon		 = NULL;
	m_szIcon	 = CSize(0, 0);
	m_dwState	 = 0;
}

BOOL CCoolTipCtrl::Create(CSize size, CWnd *pParentWnd, UINT dwStyle, UINT uID)
{
	m_nSize = size;
	m_dwStyle = dwStyle;
	return CreateEx(WS_EX_TOOLWINDOW,
					::AfxRegisterWndClass(0),
					"COOL_TIP_CTRL_WINDOW",
					WS_POPUP,
					CRect(0, 0, size.cx, size.cy),
					pParentWnd,
					uID);
}

CCoolTipCtrl::~CCoolTipCtrl()
{

}

/*################################################################
				--------------------------------------
					CoolTip control message handlers
				--------------------------------------
  ################################################################*/

BEGIN_MESSAGE_MAP(CCoolTipCtrl, CWnd)
	//{{AFX_MSG_MAP(CCoolTipCtrl)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_LBUTTONUP()
	ON_WM_TIMER()
	ON_WM_PAINT()
	ON_WM_NCPAINT()
	ON_WM_NCCALCSIZE()
	ON_WM_NCHITTEST()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

int CCoolTipCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
	{
		return -1;
	}
	
	CRect rect;
	GetClientRect(&rect);
	CDC *pdc = GetDC();
	m_MemDC.CreateCompatibleDC(pdc);
	bitmap.CreateCompatibleBitmap(pdc, m_nSize.cx, m_nSize.cy);
	oldbitmap = m_MemDC.SelectObject(&bitmap);
	ReleaseDC(pdc);

	//load dll-------------------------------------------------
	hUserDll = ::LoadLibrary(_T("USER32.dll"));
	//Change style to layered window style...
	::SetWindowLong(m_hWnd, GWL_EXSTYLE, ::GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
	SetTransparent(m_hWnd, 0, 0 , LWA_ALPHA );
	
	return 0;
}

void CCoolTipCtrl::OnDestroy() 
{
	CWnd::OnDestroy();

	KillTimer(TIMER_FADE);
	KillTimer(TIMER_DELAY);
	KillTimer(TIMER_PTTEST);

	m_MemDC.SelectObject(oldbitmap);
	bitmap.DeleteObject();
	m_MemDC.DeleteDC();
}

void CCoolTipCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
{
	Hide();
	CWnd::OnLButtonUp(nFlags, point);
}

void CCoolTipCtrl::OnTimer(UINT nIDEvent) 
{
	switch (nIDEvent) 
	{
	//Delay show=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
	case TIMER_DELAY:
		m_nShowTime--;
		//Delay time over-----------------------------=
		if (m_nShowTime <= 0)
		{
			//Kill this timer-----------------------
			KillTimer(TIMER_DELAY);

			//PtTest--------------------------------
			::GetCursorPos(&m_point);
			if (!m_rcRect.PtInRect(m_point))
			{
				KillTimer(TIMER_PTTEST);
				m_dwState = TIPS_HIDE;
				return;
			}

			//Set size------------------------------
			m_point.y += 20;
			if (m_dwStyle & TIPS_AUTOSIZE)
			{
				AutoSize();
			}

			//Captrue Screen for draw shadow--------
			CDC dc;
			dc.Attach(::GetWindowDC(NULL));
			m_MemDC.BitBlt(0, 0, m_nSize.cx, m_nSize.cy, &dc, m_point.x, m_point.y, SRCCOPY);
			dc.Detach();
			dc.DeleteDC();

			//Display tip window---------------------
			SetWindowPos(&wndTopMost,
						 m_point.x, 
						 m_point.y, 
						 m_nSize.cx, 
						 m_nSize.cy,
						 SWP_SHOWWINDOW | SWP_NOACTIVATE);

			//Draw window memory dc------------------
			OnDraw(&m_MemDC);
			
			//fade out window------------------------
			SetTransparent(m_hWnd, 0, 0 , LWA_ALPHA );
			m_dwState = TIPS_FADEOUT;
			m_nFade = 0;
			SetTimer(TIMER_FADE, 30, NULL);
		}
		break;
	
	//Fade out or in window=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
	case TIMER_FADE:
		if (m_dwState == TIPS_FADEIN)
		{
			m_nFade -= 28; //Fade in
		}
		else if (m_dwState == TIPS_FADEOUT)
		{
			m_nFade += 28; //Fade out
		}

		if (m_nFade >= 230)
		{
			m_nFade = (m_dwStyle & 0x00000002) ? 230 : 255;
			m_dwState &= TIPS_NORMAL;
			KillTimer(TIMER_FADE);
			SetTimer (TIMER_PTTEST, 500, NULL);
		}
		else if (m_nFade < 0)
		{
			//Hide window-----------------
			m_nFade = 0;
			m_dwState = TIPS_HIDE;
			KillTimer(TIMER_FADE);
			KillTimer(TIMER_PTTEST);
			ShowWindow(SW_HIDE);
			if (GetStyle() & TIPS_SHOWNEXT)
			{
				m_dwStyle &= ~TIPS_SHOWNEXT;
				m_nShowTime = 1;
				m_dwState	= TIPS_DELAYSHOW;
				SetTimer(TIMER_DELAY , 100, NULL);
				SetTimer(TIMER_PTTEST, 500, NULL);
			}
		}

		SetTransparent(m_hWnd, 0, m_nFade , LWA_ALPHA );
		break;
	
	case TIMER_PTTEST:
	
		::GetCursorPos(&m_point);
		if (!m_rcRect.PtInRect(m_point))
		{
			KillTimer(TIMER_DELAY);
			KillTimer(TIMER_PTTEST);
			m_dwState = TIPS_FADEIN;
			SetTimer(TIMER_FADE, 30, NULL);
		}
		break;
		
	default:
		break;
	}
	CWnd::OnTimer(nIDEvent);
}

void CCoolTipCtrl::OnPaint() 
{
	CRect rect;
	GetClientRect(&rect);
	CPaintDC dc(this);

	CFont font, *oldfont;
	font.CreateFont(-12, 0, 0, 400, 600, 0, 0, 0, 0, 0, 0, 0, 1, "宋体");
	oldfont = dc.SelectObject(&font);
	dc.SetBkMode(TRANSPARENT);

	//Draw background ----------------------------------
	dc.FillSolidRect(rect, m_crBk);
	dc.Draw3dRect(rect, RGB(140, 140, 140), RGB(99, 99, 99));
	
	rect.InflateRect(-5, -5);
	
	//Draw title----------------------------------------
	if (m_hIcon != NULL)
	{
		::DrawIconEx(dc.m_hDC, rect.left, rect.top, m_hIcon,
				m_szIcon.cx, m_szIcon.cy, NULL, NULL, DI_NORMAL);
		rect.left += m_szIcon.cx + 5;
	}

	if (m_strTitle != "")
	{
		dc.SetTextColor(m_crTitle);
		dc.DrawText(m_strTitle, rect, DT_LEFT | DT_SINGLELINE);
		rect.top += 15;
	}
	
	font.DeleteObject();
	font.CreateFont(-12, 0, 0, 400, 400, 0, 0, 0, 0, 0, 0, 0, 1, "宋体");
	dc.SelectObject(&font);
	
	//Draw text------------------------------------
	dc.SetTextColor(m_crText);
	dc.DrawText(m_strText, rect, DT_LEFT | DT_WORDBREAK);
	
	dc.SelectObject(oldfont);
	font.DeleteObject();
}

/*===============================================================
	Set Transparent 
=================================================================*/
BOOL CCoolTipCtrl::SetTransparent(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags)
{
	BOOL	bRet = FALSE;
	typedef BOOL (WINAPI* lpfnSetTransparent)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
	
	// Check that "USER32.dll" library has been loaded successfully...
	if ( hUserDll )
	{
		lpfnSetTransparent pFnSetTransparent  = NULL;
		pFnSetTransparent  = (lpfnSetTransparent)GetProcAddress(hUserDll, "SetLayeredWindowAttributes");
		if (pFnSetTransparent )
		{
			bRet = pFnSetTransparent(hWnd, crKey, bAlpha, dwFlags);
		}
	} //if( hUserDll )

	return bRet;
} // End of SetTransparent function

/*################################################################
				--------------------------------------
					CoolTip control display handlers
				--------------------------------------
  ################################################################*/

void CCoolTipCtrl::SetRect(const CRect& rect)
{
	m_rcRect = rect;
}

void CCoolTipCtrl::SetDelayTime(int nTime)
{
	m_nDelayTime = nTime;
}

/*===============================================================
	display window
=================================================================*/
BOOL CCoolTipCtrl::Show(CPoint point)
{
	if (IsShow() && GetState() != TIPS_DELAYSHOW) 
	{
		if (m_dwState != TIPS_FADEIN) Hide();
		m_nFade = 10;
		m_dwStyle |= TIPS_SHOWNEXT;
		return FALSE;
	}
	m_point		= point;
	m_nShowTime = m_nDelayTime;
	m_dwState	= TIPS_DELAYSHOW;
	SetTimer(TIMER_DELAY , 100, NULL);
	SetTimer(TIMER_PTTEST, 500, NULL);
	return TRUE;	
}

/*===============================================================
	hide window
=================================================================*/
BOOL CCoolTipCtrl::Hide()
{
	if (m_dwState == TIPS_HIDE)
	{
		return FALSE;
	}
	m_dwState = TIPS_FADEIN;
	SetTimer(TIMER_FADE, 30, NULL);
	return TRUE;
}

BOOL CCoolTipCtrl::IsShow()
{
	return (m_dwState != TIPS_HIDE) ;
}

void CCoolTipCtrl::DrawShadow(CDC *pDC, CRect rect, COLORREF color)
{
	//Draw shadow----------------------------------------->>
	COLORREF oldcolor = RGB(255, 255, 255);
	BYTE newPixeValR, newPixeValG, newPixeValB;
	BYTE AlphaArray[6] = {140, 170, 212, 240};
	BYTE AlphaArray2[] = {170, 205, 220, 240, 240, 250, 255};
	BYTE Alpha = 0;
	
	//bottom shadow-----------------------------------------
	int i, j;
	for (j = 0; j < 4; j++)
	{
		Alpha = AlphaArray[j];
		for (i = 6; i <= rect.right - 5; i++)
		{
			oldcolor = pDC->GetPixel(i, rect.bottom - (4 - j));
		
			newPixeValR = GetRValue(oldcolor) * Alpha / 255;  
			newPixeValG = GetGValue(oldcolor) * Alpha / 255;  
			newPixeValB = GetBValue(oldcolor) * Alpha / 255;  

			pDC->SetPixel(i, rect.bottom - (4 - j), RGB(newPixeValR, newPixeValG, newPixeValB));
		}
	}
	
	//right shadow-----------------------------------------
	Alpha = 120;
	for (i = 0; i < 4; i++)
	{
		Alpha = AlphaArray[i];
		for (j = 6; j <= rect.bottom - 5; j++)
		{
			oldcolor = pDC->GetPixel(rect.right - (4 - i), j);
		
			newPixeValR = GetRValue(oldcolor) * Alpha / 255;  
			newPixeValG = GetGValue(oldcolor) * Alpha / 255;  
			newPixeValB = GetBValue(oldcolor) * Alpha / 255;  

			pDC->SetPixel(rect.right - (4 - i), j, RGB(newPixeValR, newPixeValG, newPixeValB));
		}
	}
	
	//other------------------------------------------------
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 4; j++)
		{
			if ((i + j) > 6) break;
			Alpha = AlphaArray2[j + i];

			oldcolor	= pDC->GetPixel(rect.right - 4 + i, rect.bottom - 4 + j);
			newPixeValR = GetRValue(oldcolor) * Alpha / 255;  
			newPixeValG = GetGValue(oldcolor) * Alpha / 255;  
			newPixeValB = GetBValue(oldcolor) * Alpha / 255;  
			pDC->SetPixel(rect.right - 4 + i, rect.bottom - 4 + j, RGB(newPixeValR, newPixeValG, newPixeValB));

			oldcolor	= pDC->GetPixel(rect.right - 4 + i, rect.top + 5 - j);
			newPixeValR = GetRValue(oldcolor) * Alpha / 255;  
			newPixeValG = GetGValue(oldcolor) * Alpha / 255;  
			newPixeValB = GetBValue(oldcolor) * Alpha / 255;  
			pDC->SetPixel(rect.right - 4 + i, rect.top + 5 - j, RGB(newPixeValR, newPixeValG, newPixeValB));
		
			oldcolor	= pDC->GetPixel(rect.left - i + 5, rect.bottom - 4 + j);
			newPixeValR = GetRValue(oldcolor) * Alpha / 255;  
			newPixeValG = GetGValue(oldcolor) * Alpha / 255;  
			newPixeValB = GetBValue(oldcolor) * Alpha / 255;  
			pDC->SetPixel(rect.left - i + 5, rect.bottom - 4 + j, RGB(newPixeValR, newPixeValG, newPixeValB));
		}
	}
}

void CCoolTipCtrl::OnDraw(CDC *pDC)
{

}

/*################################################################
				------------------------------------
					CoolTip control size handlers
				------------------------------------
  ################################################################*/

void CCoolTipCtrl::SetSize(CSize size)
{
	m_nSize  = size;
	CDC *pdc = GetDC();
	bitmap.DeleteObject();
	bitmap.CreateCompatibleBitmap(pdc, m_nSize.cx, m_nSize.cy);
	m_MemDC.SelectObject(&bitmap);
	ReleaseDC(pdc);
}

void CCoolTipCtrl::AutoSize()
{
	int nstrLength = m_strTitle.GetLength();
	nstrLength = nstrLength > 30 ? nstrLength : 30;

 	CSize szText = GetStringSize(m_strText, nstrLength, CSize(6, 12));
	m_nSize   = szText;
	m_nSize.cx += 14;
	m_nSize.cy += 14;
	
	if (m_strTitle != "" )
	{
		if (szText.cx < 180 && szText.cx < m_strTitle.GetLength() * 7 ) m_nSize.cx += m_strTitle.GetLength() * 7;
		if (m_nSize.cx > 194) m_nSize.cx = 194;
		m_nSize.cy += 15;		
	}

	m_nSize.cx += m_szIcon.cx + 5;
	if (m_nSize.cy < m_szIcon.cy + 14 ) m_nSize.cy = m_szIcon.cy + 14;
	SetSize(m_nSize);
}

CSize CCoolTipCtrl::GetStringSize(CString strText, int nlinecount, CSize szFont)
{
	int npos = 0;
	CSize sz(0,0);

	while (true)
	{
		npos = strText.Find('\n');
		if (npos >= 0)
		{
			if  (npos > nlinecount)
			{
				sz.cx = nlinecount;
				sz.cy += npos / nlinecount + 1;
			}
			else
			{
				sz.cx = sz.cx > npos ? sz.cx : npos;
				sz.cy += 1;
			}

			if (npos < (strText.GetLength() - 1))
			{
				strText = strText.Right(strText.GetLength() - npos - 1);
				continue;
			}
		}
		else if (npos == -1)
		{
			if  (strText.GetLength() > nlinecount)
			{
				sz.cx = nlinecount;
				sz.cy += strText.GetLength() / nlinecount + 1;
			}
			else
			{
				sz.cx = sz.cx > strText.GetLength() ? sz.cx : strText.GetLength();
				sz.cy += 1;
			}
		}
		break;
	}
	sz.cx = sz.cx * szFont.cx;
	sz.cy = sz.cy * szFont.cy;
	return sz;
}

/*################################################################
				------------------------------------
					CoolTip control text handlers
				------------------------------------
  ################################################################*/

void CCoolTipCtrl::SetText(CString strText)
{
	m_strText = strText;
}

void CCoolTipCtrl::SetTitle(CString strTitle)
{
	m_strTitle = strTitle;
}


/*################################################################
				-------------------------------------
					CoolTip control color handlers
				-------------------------------------
  ################################################################*/

void CCoolTipCtrl::SetTextColor(COLORREF crText)
{
	m_crText = crText;
}

void CCoolTipCtrl::SetBkColor(COLORREF crBk)
{
	m_crBk = crBk;
}

void CCoolTipCtrl::SetTitleColor(COLORREF crTitle)
{
	m_crTitle = crTitle;
}

/*################################################################
				------------------------------------
					CoolTip control icon handlers
				------------------------------------
  ################################################################*/

void CCoolTipCtrl::SetIcon(HICON hIcon, CSize szIcon)
{
	m_hIcon = hIcon;
	m_szIcon	 = szIcon;
}



void CCoolTipCtrl::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *lpncsp)
{
	CRect rect = lpncsp->rgrc[0];
	rect.DeflateRect(0, 0, 4, 4);
	lpncsp->rgrc[0] = rect;
}

void CCoolTipCtrl::OnNcPaint()
{
	CWindowDC dc(this);
	CRect rect;
	GetWindowRect(&rect);
	ScreenToClient(&rect);
	dc.ExcludeClipRect(&CRect(0, 0, m_nSize.cx-4, m_nSize.cy-4));
	dc.BitBlt(0, 0, m_nSize.cx, m_nSize.cy, &m_MemDC, 0, 0, SRCCOPY);
	DrawShadow(&dc, rect);
}

UINT CCoolTipCtrl::OnNcHitTest(CPoint point)
{
	return HTCAPTION ;
}